Collections, Enumerators, and Iterators
collection is a group of objects. The .NET Framework contains a large number of interfaces and classes that define and implement various types of collections . they are helpful to develop the data structures. There are built-in collections that support dynamic arrays, linked lists, stacks, queues, and hash tables.
The .NET Framework supports four general types of collections: non-generic, specialized, bit based, and generic. Generic collections are added in the c#2.0 onwards.
non-generic collections implement several fundamental data structures, including a dynamic array, stack, and queue. The non-generic collection classes and interfaces are in System.Collections.
The specialized collections operate on a specific type of data or operate in a unique way. There are also specialized collections that use a singly linked list. The specialized collections are declared in System.Collections.Specialized.
# defines one bit-based collection called BitArray. BitArray supports bitwise operations on bits, such as AND and XOR. BitArray is declared in System.Collections.
Generic collections were added by C# 2.0 and are declared in System.Collections.Generic. They are type-safe. This means that only items that are type-compatible with the type of the collection can be stored in a generic collection, thus eliminating accidental type mismatches.
All collections is the concept of an enumerator, which is supported by the IEnumerator and IEnumerable interfaces. Each collection must implement IEnumerable.
Iterators were added by C# 2.0. They simplify the process of creating classes, such as custom collections, that can be cycled through by a foreach loop.
Non-Generic Collections
The non-generic collections are defined by a set of interfaces and by the classes that implement those interfaces.
The Non-Generic Collection Interfaces |
|
Interface |
Description |
ICollection |
Defines the elements that all non-generic collections must have. |
IComparer |
Defines the Compare( ) method that performs a comparison on objects stored in a collection. |
IDictionary |
Defines a collection that consists of key/value pairs. |
IDictionaryEnumerator |
Defines the enumerator for a collection that implements IDictionary. |
IEnumerable |
Defines the GetEnumerator( ) method, which supplies the enumerator for a collection class. |
IEnumerator |
Provides methods that enable the contents of a collection to be obtained one at a time. |
IEqualityComparer |
Compares two objects for equality. (Added by C# 2.0.) |
IHashCodeProvider |
Declared obsolete by C# 2.0. Use IEqualityComparer instead. |
IList |
Defines a collection that can be accessed via an indexer. |
Non-Generic Collection Classes
Class |
Description |
ArrayList |
A dynamic array. This is an array that can grow as needed. |
Hashtable |
A hash table for key/value pairs. |
Queue |
A first-in, first-out list. |
SortedList |
A sorted list of key/value pairs. |
Stack |
A first-in, last-out list. |
The ArrayList class supports dynamic arrays, which can grow or shrink as needed. An ArrayList is a variable-length array of object references that can dynamically increase or decrease in size.
ArrayList implements ICollection, IList, IEnumerable, and ICloneable. ArrayList
Constructors
public ArrayList( )
public ArrayList(ICollection c)
public ArrayList(int capacity)
Program on ArrayList
using System;
using System.Collections;
class Sample
{
public static void Main()
{
ArrayList al = new ArrayList();
Console.WriteLine("elements: " +al.Count);
al.Add('C');
al.Add('A');
al.Add('E');
al.Add('B');
al.Add('D');
al.Add('F');
Console.WriteLine("Number of elements: " +al.Count);
Console.Write("Current contents: ");
for (int i = 0; i < al.Count; i++)
Console.Write(al[i] + " ");
al.Remove('F');
al.Remove('A');
Console.WriteLine("Number of elements: " +al.Count);
foreach (char c in al)
Console.Write(c + " ");
al[0] = 'X';
al[1] = 'Y';
al[2] = 'Z';
Console.Write("Contents: ");
foreach (char c in al)
Console.Write(c + " ");
}
}
Program on Arraylist to Array
using System;
using System.Collections;
class Sample
{
public static void Main()
{
ArrayList al = new ArrayList();
al.Add(1);
al.Add(2);
al.Add(3);
al.Add(4);
Console.Write("Contents: ");
foreach (int i in al)
Console.Write(i + " ");
int[] ia = (int[])al.ToArray(typeof(int));
for (int i = 0; i < ia.Length; i++)
Console.WriteLine(ia[i]);
}
}
hash table stores information using a mechanism called hashing. In hashing, the informational content of a key is used to determine a unique value, called its hash code. The hash code is then used as the index at which the data associated with the key is stored in the table. Hashtable implements the IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback, and ICloneable interfaces.
Constructors
public Hashtable( )
public Hashtable(IDictionary c)
public Hashtable(int capacity)
public Hashtable(int capacity, float fillRatio)
Program on hash table
using System;
using System.Collections;
class Sample
{
public static void Main()
{
Hashtable ht = new Hashtable();
ht.Add("v", "Vision");
ht.Add("p", "Prasad");
ht.Add("c", "Computers");
ht.Add("h", "Hyderabad");
ht["m"] = "Mechine";
ICollection c = ht.Keys;
foreach (string str in c)
Console.WriteLine(str + ": " + ht[str]);
}
}
SortedList
SortedList creates a collection that stores key/value pairs in sorted order, based on the value of the keys. SortedList implements the IDictionary, ICollection, IEnumerable, and ICloneable interfaces.
Constructors
public SortedList( )
public SortedList(IDictionary c)
public SortedList(int capacity)
public SortedList(IComparer comp)
Program on Sorted List
using System;
using System.Collections;
class sample
{
public static void Main()
{
SortedList s1 = new SortedList();
s1.Add("v", "Vision");
s1.Add("p", "Prasad");
s1.Add("c", "Computers");
s1.Add("h", "Hyderabad");
s1["m"] = "Mechine";
ICollection c = s1.Keys;
Console.WriteLine("Contents of list via indexer.");
foreach (string str in c)
Console.WriteLine(str + ": " + s1[str]);
Console.WriteLine("Contents by integer indexes.");
for (int i = 0; i < s1.Count; i++)
Console.WriteLine(s1.GetByIndex(i));
Console.WriteLine();
// Show integer indexes of entries.
Console.WriteLine("Integer indexes of entries.");
foreach (string str in c)
Console.WriteLine(str + ": " + s1.IndexOfKey(str));
}
}
Stack
The stack is one of the most important data structures in computing. a stack is a first-in, last-out list. It implements the ICollection, IEnumerable, and ICloneable interfaces.
public Stack( )
public Stack(int capacity)
public Stack(ICollection c)
Program on Stack Class
using System;
using System.Collections;
class Sample
{
static void showPush(Stack st, int a)
{
st.Push(a);
Console.WriteLine("Push(" + a + ")");
Console.Write("stack: ");
foreach (int i in st)
Console.Write(i + " ");
}
static void showPop(Stack st)
{
Console.Write("Pop -> ");
int a = (int)st.Pop();
Console.WriteLine(a);
Console.Write("stack: ");
foreach (int i in st)
Console.Write(i + " ");
}
public static void Main()
{
Stack st = new Stack();
foreach (int i in st)
Console.Write(i + " ");
showPush(st, 22);
showPush(st, 65);
showPush(st, 91);
showPop(st);
showPop(st);
showPop(st);
try
{
showPop(st);
}
catch (InvalidOperationException)
{
Console.WriteLine("Stack empty.");
}
}
}
Queue
Another familiar data structure is the queue, which is a first-in, first-out list. That is, the first item put in a queue is the first item retrieved.
public Queue( )
public Queue (int capacity)
public Queue (int capacity, float growFact)
public Queue (ICollection c)
Program On Queue class
using System;
using System.Collections;
class Vision
{
static void insert(Queue q, int a)
{
q.Enqueue(a);
Console.WriteLine("Inserted(" + a + ")");
}
static void delete(Queue q)
{
Console.Write("Deleted -> ");
int a = (int)q.Dequeue();
Console.WriteLine(a);
}
static void disp(Queue q)
{
Console.Write("queue: ");
foreach (int i in q)
Console.Write(i + " ");
Console.WriteLine();
}
public static void Main()
{
Queue q = new Queue();
foreach (int i in q)
Console.Write(i + " ");
Console.WriteLine();
insert (q, 22);
insert (q, 65);
insert (q, 91);
disp (q);
delete(q);
disp(q);
delete (q);
delete (q);
disp(q);
try
{
delete (q);
}
catch (InvalidOperationException)
{
Console.WriteLine("Queue empty.");
}
}
}
Generic Collections
The generic collections are declared in the System.Collections.Generic namespace. there is a generic collection called LinkedList that implements a doubly linked list, but there is no non-generic equivalent. the generic version of ArrayList is called List, and the generic version of Hashtable is called Dictionary.
The generic collections are defined by a set of interfaces and the classes that implement those interfaces.
The Generic Collection Interfaces |
|
Interface |
Description |
ICollection<T> |
Defines the foundational features for the generic collections. |
IComparer<T> |
Defines the generic Compare( ) method that performs a comparison on objects stored in a collection. |
IDictionary<TK, TV> |
Defines a generic collection that consists of key/value pairs. |
IEnumerable<T> |
Defines the generic GetEnumerator( ) method, which supplies the enumerator for a collection class. |
IEnumerator<T> |
Provides members that enable the contents of a collection to be obtained one at a time. |
IEqualityComparer<T> |
Compares two objects for equality. |
IList<T> |
Defines a generic collection that can be accessed via an indexer. |
Generic Collection Classes |
|
Class |
Description |
Dictionary<TK, TV> |
Stores key/value pairs. Provides functionality similar to that found in the non-generic Hashtable class. |
LinkedList<T> |
Stores elements in a doubly linked list. |
List<T> |
A dynamic array. Provides functionality similar to that found in the non-generic ArrayList class. |
Queue<T> |
A first-in, first-out list. Provides functionality similar to that found in the non-generic Queue class. |
SortedDictionary<TK, TV> |
A sorted list of key/value pairs. |
SortedList<TK, TV> |
A sorted list of key/value pairs. Provides functionality similar to that found in the non-generic SortedList class. |
Stack<T> |
A first-in, last-out list. Provides functionality similar to that found in the non-generic Stack class. |
List<T> Collection
The List<T> class implements a generic, dynamic array and is conceptually similar to the non-generic ArrayList class. List<T> implements both the generic and non-generic forms of the ICollection, IList, and IEnumerable interfaces.
Constructors
public List( )
public List(IEnumerable<T> c)
public List(int capacity)
Program on Lists with Generics
using System;
using System.Collections.Generic;
class vision
{
public static void Main()
{
List<char> lst = new List<char>();
Console.WriteLine("Initial number of elements: " +
lst.Count);
lst.Add('C');
lst.Add('A');
lst.Add('E');
lst.Add('B');
lst.Add('D');
lst.Add('F');
Console.WriteLine("Number of elements: " +
lst.Count);
Console.Write("Current contents: ");
for (int i = 0; i < lst.Count; i++)
Console.Write(lst[i] + " ");
Console.WriteLine("\n");
lst.Remove('F');
lst.Remove('A');
Console.WriteLine("Number of elements: " +
lst.Count);
// Use foreach loop to display the list.
Console.Write("Contents: ");
foreach (char c in lst)
Console.Write(c + " ");
Console.WriteLine("Current capacity: " +
lst.Capacity);
lst[0] = 'X';
lst[1] = 'Y';
lst[2] = 'Z';
Console.Write("Contents: ");
foreach (char c in lst)
Console.Write(c + " ");
}
}
The LinkedList<T> class implements a generic doubly linked list. It implements ICollection, ICollection<T>, IEnumerable, IEnumerableI<T>, Serializable, and IDeserializationCallback. Like most linked list implementations, LinkedList<T> encapsulates the values stored in the list in nodes that contain links to the previous and next element in the list. These nodes are objects of type LinkedListNode<T>.
Constructors
public LinkedList( )
public LinkedList(IEnumerable<T> c)
Program on Linked lists with generics
using System;
using System.Collections.Generic;
class vision
{
public static void Main()
{
LinkedList<char> ll = new LinkedList<char>();
ll.AddFirst('A');
ll.AddFirst('B');
ll.AddFirst('C');
ll.AddFirst('D');
ll.AddFirst('E');
Console.WriteLine("Number of elements: " +
ll.Count);
LinkedListNode<char> node;
Console.Write("Display contents by following links: ");
for (node = ll.First; node != null; node = node.Next)
Console.Write(node.Value + " ");
Console.WriteLine("\n");
Console.WriteLine("\n");
Console.Write("Follow links backwards: ");
for (node = ll.Last; node != null; node = node.Previous)
Console.Write(node.Value + " ");
ll.Remove('C');
ll.Remove('A');
Console.WriteLine("Number of elements: " +
ll.Count);
Console.Write("Contents after deletion: ");
foreach (char ch in ll)
Console.Write(ch + " ");
// Add three elements to the end of the list.
ll.AddLast('X');
ll.AddLast('Y');
ll.AddLast('Z');
Console.Write("Contents after addition to end: ");
foreach (char ch in ll)
Console.Write(ch + " ");
}
}
Dictionary<TK, TV> Class
The Dictionary<TK, TV> class stores key/value pairs. In a dictionary, values are accessed through their keys. In this regard it is similar to the non-generic Hashtable class. Dictionary<TK, TV> implements both the generic and non-generic forms of IDictionary, ICollection, and IEnumerable. It also implements ISerializable and IDeserializationCallback..
Constructors
public Dictionary( )
public Dictionary(IDictionary<TK, TV> dict)
public Dictionary(int capacity)
Program on Dictionay class
using System.Collections.Generic;
using System;
class GenDictionaryDemo
{
public static void Main()
{
Dictionary<string, double> d =
new Dictionary<string, double>();
d.Add("Prasasd", 4300);
d.Add("Vision", 73000);
d.Add("Ram", 59000);
d.Add("Mohan", 45000);
d.Add("Sonu", 99000);
ICollection<string> c = d.Keys;
foreach (string str in c)
Console.WriteLine("{0}, Salary: {1:C}", str, d[str]);
}
}
SortedDictionary<TK, TV> Class
The SortedDictionary<TV, TK> class stores key/value pairs and is similar to Dictionary<TK, TV> except that it is sorted by key. SortedDictionary<TK, TV> implements both the generic and non-generic forms of IDictionary, ICollection, and IEnumerable.
Constructors
public SortedDictionary( )
public SortedDictionary(IDictionary<TK, TV> dict)
public SortedDictionary(IComparer<TK> comp)
public SortedDictionary(IDictionary<TK, TV> dict, IComparer<TK> comp)
Program on SortedDictonary Class
using System.Collections.Generic;
using System;
class GenDictionaryDemo
{
public static void Main()
{
SortedDictionary<string, double> d =
new SortedDictionary<string, double>();
d.Add("Prasasd", 4300);
d.Add("Vision", 73000);
d.Add("Ram", 59000);
d.Add("Mohan", 45000);
d.Add("Sonu", 99000);
ICollection<string> c = d.Keys;
foreach (string str in c)
Console.WriteLine("{0}, Salary: {1:C}", str, d[str]);
}
}
Stack<T> Class
Stack<T> is the generic equivalent of the non-generic Stack class. Stack<T> supports a first-in, last-out stack. It implements the ICollection, IEnumerable<T>, and IEnumerable interfaces.
Constructors
public Stack( )
public Stack(int capacity)
public Stack(IEnumerable<T> c)
Programs on stacks using generics
using System;
using System.Collections.Generic;
class Vision
{
public static void Main()
{
Stack<string> st = new Stack<string>();
st.Push("One");
st.Push("Two");
st.Push("Three");
st.Push("Four");
st.Push("Five");
while (st.Count > 0)
{
string str = st.Pop();
Console.Write(str + " ");
}
Console.WriteLine();
}
}
Queue<T> Class
Queue<T> is the generic equivalent of the non-generic Queue class. It supports a first-in, first-out list. Queue<T> implements the ICollection, IEnumerable<T>, and IEnumerable interfaces.
Constructors
public Queue( )
public Queue (int capacity)
public Queue (IEnumerable c)
Program on Generic Queues
using System;
using System.Collections.Generic;
class vision
{
public static void Main()
{
Queue<double> q = new Queue<double>();
q.Enqueue(98.6);
q.Enqueue(212.0);
q.Enqueue(32.0);
q.Enqueue(3.1416);
double sum = 0.0;
foreach (double d in q)
Console.WriteLine("Contents:"+d);
}
}
IComparable
If you want to sort objects that are stored in a non-generic collection, then you will implement the non-generic version of IComparable. It defines only one method, CompareTo( ).
Program on IComparable
using System;
using System.Collections;
class Inventory : IComparable {
string name;
double cost;
int onhand;
public Inventory(string n, double c, int h) {
name = n;
cost = c;
onhand = h;
}
public override string ToString() {
return
String.Format("{0,-10}Cost: {1,6:C} On hand: {2}",
name, cost, onhand);
}
public int CompareTo(object obj) {
Inventory b;
b = (Inventory) obj;
return name.CompareTo(b.name);
}
}
class vision {
public static void Main() {
ArrayList inv = new ArrayList();
inv.Add(new Inventory("Rin", 5.95, 3));
inv.Add(new Inventory("Arial", 8.29, 2));
inv.Add(new Inventory("Surf", 3.50, 4));
inv.Add(new Inventory("Nirma", 19.88, 8));
Console.WriteLine("Inventory list before sorting:");
foreach(Inventory i in inv) {
Console.WriteLine(" " + i);
}
Console.WriteLine();
inv.Sort();
Console.WriteLine("Inventory list after sorting:");
foreach(Inventory i in inv) {
Console.WriteLine(" " + i);
}
}
}
Program in IComparable generics
using System;
using System.Collections.Generic;
class Inventory : IComparable<Inventory>
{
string name;
double cost;
int onhand;
public Inventory(string n, double c, int h)
{
name = n;
cost = c;
onhand = h;
}
public override string ToString()
{
return
String.Format("{0,-10}Cost: {1,6:C} On hand: {2}",
name, cost, onhand);
}
public int CompareTo(Inventory obj)
{
return name.CompareTo(obj.name);
}
}
class vision
{
public static void Main()
{
List<Inventory> inv = new List<Inventory>();
inv.Add(new Inventory("Rin", 5.95, 3));
inv.Add(new Inventory("Arial", 8.29, 2));
inv.Add(new Inventory("Surf", 3.50, 4));
inv.Add(new Inventory("Nirma", 19.88, 8));
Console.WriteLine("Inventory list before sorting:");
foreach (Inventory i in inv)
{
Console.WriteLine(" " + i);
}
Console.WriteLine();
// Sort the list.
inv.Sort();
Console.WriteLine("Inventory list after sorting:");
foreach (Inventory i in inv)
{
Console.WriteLine(" " + i);
}
}
}
Enumerator
An enumerator is an object that implements either the non-generic IEnumerator or the generic IEnumerator<T> interface.
Program on Enumerator
using System;
using System.Collections;
class vision
{
public static void Main()
{
ArrayList list = new ArrayList(1);
for (int i = 0; i < 10; i++)
list.Add(i);
// Use enumerator to access list.
IEnumerator etr = list.GetEnumerator();
while (etr.MoveNext())
Console.Write(etr.Current + " ");
Console.WriteLine();
// Re-enumerate the list.
etr.Reset();
while (etr.MoveNext())
Console.Write(etr.Current + " ");
Console.WriteLine();
}
}
IEnumerable and IEnumerator
If you want to create a class that contains objects that can be enumerated via a foreach loop, then that class must implement IEnumerator. It must also implement IEnumerable. In other words, to enable an object of a class that you create to be used in a foreach loop, you must implement IEnumerator and IEnumerable, using either their generic or non-generic form.
Program on IEnumerable and IEnumerator
using System;
using System.Collections;
class abc: IEnumerator, IEnumerable
{
char[] chrs = { 'A', 'B', 'C', 'D' };
int idx = -1;
public IEnumerator GetEnumerator()
{
return this;
}
public object Current
{
get
{
return chrs[idx];
}
}
// Advance to the next object.
public bool MoveNext()
{
if (idx == chrs.Length - 1)
{
Reset(); // reset enumerator at the end.
return false;
}
idx++;
return true;
}
// Reset the enumerator to the start.
public void Reset() { idx = -1; }
}
class vision
{
public static void Main()
{
abc mc = new abc();
foreach (char ch in mc)
Console.Write(ch + " ");
Console.WriteLine();
foreach (char ch in mc)
Console.Write(ch + " ");
Console.WriteLine();
}
}
Iterators
An iterator is a method, operator, or accessor that returns the members of a set of objects, one member at a time, from start to finish.
Program on Iterator
using System;
using System.Collections;
class abc
{
char[] chrs = { 'A', 'B', 'C', 'D' };
public IEnumerator GetEnumerator()
{
foreach (char ch in chrs)
yield return ch;
}
}
class vision
{
public static void Main()
{
abc mc = new abc();
foreach (char ch in mc)
Console.Write(ch + " ");
Console.WriteLine();
}
}
You can stop an iterator early by using this form of the yield statement:
yield break;
Program on Stoping iterator
using System;
using System.Collections;
class abc
{
char ch = 'A';
public IEnumerator GetEnumerator()
{
for (int i = 0; i < 26; i++)
{
if (i == 10) yield break; // stop iterator early
yield return (char)(ch + i);
}
}
}
class vision
{
public static void Main()
{
abc mc = new abc();
foreach (char ch in mc)
Console.Write(ch + " ");
Console.WriteLine();
}
}
Program on GenericIterator
using System;
using System.Collections.Generic;
class abc<T>
{
T[] array;
public abc(T[] a)
{
array = a;
}
public IEnumerator<T> GetEnumerator()
{
foreach (T obj in array)
yield return obj;
}
}
class vision
{
public static void Main()
{
int[] nums = { 4, 3, 6, 4, 7, 9 };
abc<int> mc = new abc<int>(nums);
foreach (int x in mc)
Console.Write(x + " ");
Console.WriteLine();
bool[] bVals = { true, true, false, true };
abc<bool> mc2 = new abc<bool>(bVals);
foreach (bool b in mc2)
Console.Write(b + " ");
Console.WriteLine();
}
}